<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
use app\common\lib\RespCode;
use custom\Curl;
use custom\Err;
use custom\Log;
use custom\Redis;
use map\BaiDu;
use oss\Oss;
use think\Db;
use think\facade\Env;

/**
 * 随机生成32位字符串
 * @param int $length
 * @return string
 */
function get_nonce_str($length = 32) {
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $str = "";
    for ($i = 0; $i < $length; $i++) {
        $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
    }
    return $str;
}

/**
 * 时间格式验证
 * @param $time
 * @param string $type
 * @return bool
 */
function validTime($time, $type = 'Y-m-d H:i') {

    if ($type == 'Y-m-d H:i' && !preg_match("/^[0-9]{4}\-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}\:[0-9]{1,2}$/", $time)) {
        return false;
    }

    if ($type == 'Y-m-d' && !preg_match("/^[0-9]{4}\-[0-9]{1,2}-[0-9]{1,2}$/", $time)) {
        return false;
    }

    if ($type == 'Y-m-d H:i:s' && !preg_match("/^[0-9]{4}\-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}$/", $time)) {
        return false;
    }

    return true;
}

/**
 * 格式化时间
 * @param $time
 * @param string $type
 * @return false|string
 */
function format_time($time, $type = 'Y-m-d H:i:s') {

    return date($type, $time);
}

/**
 * 是否是手机
 * @return bool
 */
function isMobile() {

    if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) {
        return true;
    }

    if (isset ($_SERVER['HTTP_VIA'])) {

        return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
    }

    if (isset ($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = [
            'nokia',
            'sony',
            'ericsson',
            'mot',
            'samsung',
            'htc',
            'sgh',
            'lg',
            'sharp',
            'sie-',
            'philips',
            'panasonic',
            'alcatel',
            'lenovo',
            'iphone',
            'ipod',
            'blackberry',
            'meizu',
            'android',
            'netfront',
            'symbian',
            'ucweb',
            'windowsce',
            'palm',
            'operamini',
            'operamobi',
            'openwave',
            'nexusone',
            'cldc',
            'midp',
            'wap',
            'mobile'
        ];

        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
            return true;
        }
    }

    if (isset ($_SERVER['HTTP_ACCEPT'])) {


        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
            return true;
        }
    }
    return false;
}

/**
 * 生成12位唯一ID，到2075年有效
 * 默认会按顺序生成
 * @param string $prev_char 前缀字符，默认为a-z的随机数
 * @return string
 */
function uniqid12($prev_char = '') {
    // 距2015年的微秒, 60年范围内
    $nowmics = explode(' ', microtime());
    $sec = substr('00' . base_convert(substr(($nowmics [1] - 1420041600), -9), 10, 36), -6);
    $msec = substr('00' . base_convert(substr($nowmics [0], 2, -2), 10, 36), -4);
    // 最后一位随机产生
    return $prev_char . $sec . $msec . base_convert(mt_rand(0, 35), 10, 36) . base_convert(mt_rand(0, 35), 10, 36);
}

/**
 * 生成16位唯一ID，到2075年有效
 * 默认会按顺序生成
 * @param string $prev_char 前缀字符，默认为a-z的随机数
 * @return string
 */
function uniqid16($prev_char = '') {
    // 距2015年的微秒, 60年范围内
    $nowmics = explode(' ', microtime());
    $sec = substr('00' . base_convert(substr(($nowmics[1] - 1420041600), -9), 10, 36), -6);  // 秒
    $msec = substr('00' . base_convert(substr($nowmics[0], 2, -2), 10, 36), -4); // 微妙
    $mem = substr('00' . base_convert(memory_get_usage(), 10, 36), -4); // 内存用量
    // 最后两位随机产生
    return $prev_char . $sec . $msec . $mem . base_convert(mt_rand(0, 35), 10, 36) . base_convert(mt_rand(0, 35), 10, 36);
}

/**
 * 是否为索引数组
 * @param $array
 * @return bool
 */
function is_assoc($array) {
    if (is_array($array)) {
        $keys = array_keys($array);
        return $keys != array_keys($keys);
    }
    return false;
}

/**
 * 判断是否绝对路径
 * @param string $path 路径
 * @return boolean
 */
function is_absolute_path($path) {
    return substr($path, 0, 1) === '/' || substr($path, 1, 1) === ':';
}

/**
 * 分页处理
 * @param $total int 总量
 * @param $num int 分页数量
 * @return int
 */
function page_num($total, $num) {
    if ($total % $num) {
        $page = intval($total / $num) + 1;
    } else {
        $page = intval($total / $num);
    }
    return $page;
}

/**
 * 详细时间
 * @param $time
 * @return false|string
 */
function detail_time($time) {
    return date("Y-m-d H:i", $time);
}

/**
 * 写入文件，如果没有该目录则创建该目录
 * @param string $filename 文件名
 * @param string $data 文件内容
 * @param int $flags 写入方式，参考file_put_contents flags
 * @return boolean
 */
function file_put_autodir($filename, $data, $flags) {
    $pathname = dirname($filename); // 先建立目录
    is_dir($pathname) or @ mkdir($pathname, 0777, true);
    $rs = file_put_contents($filename, $data, $flags);
    return $rs;
}

/**
 * 获取文件后缀名
 * @param $filename
 * @return mixed
 */
function get_ext($filename) {
    $arr = explode('.', $filename);
    return end($arr);
}

/**
 * 通过key获取数组
 * @param $data
 * @param $fields
 * @return array
 */
function get_array_by_keys($data, $fields) {
    $fields = is_string($fields) ? explode(',', $fields) : $fields;
    $res = [];
    foreach ($fields as $field) {
        isset($data[$field]) && $res[$field] = $data[$field];
    }
    return $res;
}

/**
 * 不获取包含的keys
 * @param $data
 * @param $fields
 * @return array
 */
function no_array_by_keys($data, $fields) {
    $fields = is_string($fields) ? explode(',', $fields) : $fields;
    foreach ($fields as $field) {
        if (isset($data[$field])) {
            unset($data[$field]);
        }
    }
    return $data;
}

/**
 * 金额格式化
 * @param $money
 * @param int $type 类型：1元转分、2分转元、3分转万
 * @return float|int
 * @throws \think\Exception
 */
function moneyFormat($money, $type = 1) {
    if (empty($money)) {
        return 0;
    }
    switch ($type) {
        case 1:
            return intval($money * 100);
            break;
        case 2:
            return round($money / 100, 2);
            break;
        case 3:
            return intval($money / 1000000);
        default:
            throw new \think\Exception('金额转换失败', RespCode::PARAMS_ERR);
    }
}

/**
 * 根据字符串返回首字母
 * @param $str
 * @return string
 */
function initials($str) {
    if (empty($str)) {
        return '';
    }

    $fchar = ord($str[0]);

    if ($fchar >= ord('A') && $fchar <= ord('z')) {
        return strtoupper($str[0]);
    }
    $s1 = mb_convert_encoding($str, "gb2312", "UTF-8");
    $s2 = mb_convert_encoding($s1, "UTF-8", "gb2312");
    $s = $s2 == $str ? $s1 : $str;
    $asc = ord($s{0}) * 256 + ord($s{1}) - 65536;
    if ($asc >= -20319 && $asc <= -20284) {
        return 'A';
    }
    if ($asc >= -20283 && $asc <= -19776) {
        return 'B';
    }
    if ($asc >= -19775 && $asc <= -19219) {
        return 'C';
    }

    if ($asc >= -19218 && $asc <= -18711) {
        return 'D';
    }

    if ($asc >= -18710 && $asc <= -18527) {
        return 'E';
    }

    if ($asc >= -18526 && $asc <= -18240) {
        return 'F';
    }

    if ($asc >= -18239 && $asc <= -17923) {
        return 'G';
    }

    if ($asc >= -17922 && $asc <= -17418) {
        return 'H';
    }

    if ($asc >= -17417 && $asc <= -16475) {
        return 'J';
    }

    if ($asc >= -16474 && $asc <= -16213) {
        return 'K';
    }

    if ($asc >= -16212 && $asc <= -15641) {
        return 'L';
    }

    if ($asc >= -15640 && $asc <= -15166) {
        return 'M';
    }

    if ($asc >= -15165 && $asc <= -14923) {
        return 'N';
    }

    if ($asc >= -14922 && $asc <= -14915) {
        return 'O';
    }

    if ($asc >= -14914 && $asc <= -14631) {
        return 'P';
    }

    if ($asc >= -14630 && $asc <= -14150) {
        return 'Q';
    }

    if ($asc >= -14149 && $asc <= -14091) {
        return 'R';
    }

    if ($asc >= -14090 && $asc <= -13319) {
        return 'S';
    }

    if ($asc >= -13318 && $asc <= -12839) {
        return 'T';
    }

    if ($asc >= -12838 && $asc <= -12557) {
        return 'W';
    }

    if ($asc >= -12556 && $asc <= -11848) {
        return 'X';
    }

    if ($asc >= -11847 && $asc <= -11056) {
        return 'Y';
    }

    if ($asc >= -11055 && $asc <= -10247) {
        return 'Z';
    }

    return "#";
}

/**
 * 获取当前时间-毫秒
 * @return int
 */
function get_microtime() {
    return intval(microtime(true) * 1000);
}

/**
 * 去除二维数组重复值,默认重复保留前面的值
 *array 二维数组
 *keyid 需要判断是否重复的项目
 *desc 为true时保留后面的
 */
function array_repeat($array, $keyid = "id", $desc = false) {
    $array = array_values($array);
    //倒叙排列数
    if ($desc) {
        $array = array_rsort($array, true);
    }

    //提取需要判断的项目变成一维数组
    $a = array_tq($array, $keyid);

    //去除一维数组重复值
    $a = array_unique($a);
    //提取二维数组项目值
    foreach ($array[0] AS $key => $value) {
        $akey[] = $key;
    }
    //重新拼接二维数组
    foreach ($akey AS $key => $value) {
        $b = array_tq($array, $value);
        foreach ($a AS $key2 => $value2) {
            $c[$key2][$value] = $b[$key2];
        }
    }

    if ($desc) {
        $c = array_rsort($c, true);
    }
    return $c;
}

//数组倒叙
function array_rsort($arr, $isvalues = false) {
    if (is_array($arr)) {
        $flag = false;
        //一维数组
        if (count($arr) == count($arr, 1)) {
            $flag = true;
            $i = 0;
            //转换成二维数组
            foreach ($arr AS $key => $value) {
                $a[$i]["okey"] = $key;
                $a[$i]["value"] = $value;
                $i++;
            }
            $arr = $a;
        } //多维数组
        else {
            //添加临时key值
            foreach ($arr AS $key => $value) {
                $value["okey"] = $key;
                $array[] = $value;
            }
            $arr = $array;
        }

        //倒叙并还原key值
        $count = count($arr) - 1;
        for ($i = 0; $i < count($arr); $i++) {
            $b[$arr[$count]["okey"]] = $arr[$count];
            $count--;
        }

        //重构一维数组
        if ($flag == true) {
            foreach ($b AS $key => $value) {
                if ($isvalues) {
                    $c[] = $value["value"];
                } else {
                    $c[$value["okey"]] = $value["value"];
                }
            }
        } //多维数组去除临时key值
        else {
            foreach ($b AS $key => $value) {
                unset($value["okey"]);
                if ($isvalues) {
                    $c[] = $value;
                } else {
                    $c[$key] = $value;
                }
            }
        }
        return $c;
    }
}

//提取二维数组项目
function array_tq($array, $aval = "") {
    foreach ($array AS $key => $value) {
        $result[] = $value[$aval];
    }
    return $result;
}

/**
 * 二维数提取键，重复的数据附加新键
 * @param $arr
 * @param $field
 * @return mixed
 */
function array_field_repeat($arr, $field) {
    //提取需求处理的项目
    $fields = array_column($arr, $field);
    //提取出现出现的频率
    $_repeat = array_count_values($fields);
    $ret = [];
    //提取频率大于1次的数据
    foreach ($_repeat as $k1 => $v1) if ($v1 > 1) $ret[] = $k1;
    //给数据附加新元素
    foreach ($arr as $k2 => $v2) {
        if (in_array($v2[$field], $ret)) $arr[$k2]['is_repeat'] = 1;
        else $arr[$k2]['is_repeat'] = 0;
    }
    return $arr;
}

/**
 * 生成二维码
 * @param $data
 * @param $filename
 * @param string $dir
 * @param string $logo
 * @return string
 */
function get_qr_code($data, $filename, $dir = '', $logo = '') {
    require_once Env::get('root_path') . 'third/phpqrcode/phpqrcode.php';
    $level = 'QR_ECLEVEL_L'; // L-smallest, M, Q, H-best
    $size = 3; // 1-50
    $margin = 4;
    $dir === '' && $dir = dirname(dirname(dirname(__FILE__))) . '/_/static' . DIRECTORY_SEPARATOR . 'qrcode' . DIRECTORY_SEPARATOR;
    if (!is_dir($dir)) {
        mkdir($dir, 0777, true);
    }
    $file = $dir . $filename . '.png';
    QRcode::png($data, $file, $level, $size, $margin, true);

    if ($logo) {
        $QR = imagecreatefromstring(file_get_contents($file));

        $logo = imagecreatefromstring(file_get_contents($logo));

        $QR_width = imagesx($QR);

        $QR_height = imagesy($QR);

        $logo_width = imagesx($logo);//logo图片宽度

        $logo_height = imagesy($logo);//logo图片高度

        $logo_qr_width = $QR_width / 5;

        $scale = $logo_width / $logo_qr_width;

        $logo_qr_height = $logo_height / $scale;

        $from_width = ($QR_width - $logo_qr_width) / 2;


        imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);


        imagepng($QR, $file);
        imagedestroy($QR);
    }
    return basename($file);
}

/**
 * 创建存储目录
 * @param $path
 * @return bool
 */
function mkdirs($path) {
    if (!is_dir($path)) {
        mkdirs(dirname($path));
        mkdir($path);
    }
    return is_dir($path);
}

/**
 * 生成文件名
 * @param $dir
 * @param $ext
 * @return string
 */
function file_random_name($dir, $ext) {
    do {
        $filename = random(30) . '.' . $ext;
    } while (file_exists($dir . $filename));

    return $filename;
}

/**
 * 文件名处理
 * @param $length
 * @param bool $numeric
 * @return string
 */
function random($length, $numeric = FALSE) {
    $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
    $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
    if ($numeric) {
        $hash = '';
    } else {
        $hash = chr(rand(1, 26) + rand(0, 1) * 32 + 64);
        $length--;
    }
    $max = strlen($seed) - 1;
    for ($i = 0; $i < $length; $i++) {
        $hash .= $seed{mt_rand(0, $max)};
    }
    return $hash;
}

/**
 * 保存上传文件
 * @param $filename
 * @param $dest
 * @return bool
 */
function file_move($filename, $dest) {
    mkdirs(dirname($dest));
    if (is_uploaded_file($filename)) {
        move_uploaded_file($filename, $dest);
    } else {
        rename($filename, $dest);
    }
    return is_file($dest);
}

/**
 * 是否在区间内
 * @param $num
 * @param $section
 * @return bool
 */
function is_section($num, $section) {
    is_string($section) && $section = explode('-', $section);
    list($min, $max) = $section;
    if ($min == 0) {
        return $num < $max;
    }
    if ($max == 0) {
        return $num > $min;
    }
    return $min <= $num && $max >= $num;
}

/**
 * 浮点数转整数
 * @desc 如果浮点数小数点位数大于传的小数点位数，会截取掉多余部分
 * @param $float 浮点数
 * @param $spot 小数位数
 * @return int
 */
function floatInt($float, $spot) {
    if (empty($float)) {
        return 0;
    }
    $floatStr = (string)$float;
    $arr = explode('.', $floatStr);
    $int = $arr[0];
    $decimal = str_repeat('0', $spot);
    if (isset($arr[1])) {
        $len = strlen($arr[1]);
        $len < $spot && $decimal = $arr[1] . str_repeat('0', $spot - $len);
        $len > $spot && $decimal = substr($arr[1], 0, $spot);
    }
    return intval($int . $decimal);
}

/**
 * 整数转浮点数字符串
 * @desc 如果整数长度小于小数点位数，那么在整数前用零自动补位
 * @param $int 整数
 * @param $spot 小数位数
 * @return string
 */
function intFloatStr($int, $spot) {
    $intStr = (string)$int;
    $len = strlen($intStr);
    if ($len == $spot) {
        $int = '0';
        $decimal = $intStr;
    } elseif ($len > $spot) {
        $int = substr($intStr, 0, $len - $spot);
        $decimal = substr($intStr, $spot * -1);
    } else {
        $int = '0';
        $decimal = str_repeat('0', $spot - $len);
    }
    $decimal = rtrim($decimal, 0);
    return $decimal == '' ? (string)$int : "{$int}.{$decimal}";
}

/**
 * 浮点数求和
 * @desc 相同位数的浮点数
 * @param $float1 浮点数1
 * @param $float2 浮点数2
 * @param $spot 浮点数位数
 * @param int $rType 返回类型：1整数、2小数
 * @return int|string
 */
function floatSum($float1, $float2, $spot, $rType = 1) {
    $int1 = floatInt($float1, $spot);
    $int2 = floatInt($float2, $spot);
    $int = $int1 + $int2;
    if ($rType == 1) {
        return $int;
    }

    return intFloatStr($int, $spot);
}

/**
 * 浮点数求积（乘积）
 * @desc 相同位数的浮点数
 * @param $float1 浮点数1
 * @param $float2 浮点数2
 * @param $spot 浮点数位数
 * @param int $rType 返回类型：1整数、2小数
 * @return int|string
 */
function floatRide($float1, $float2, $spot, $rType = 1) {
    $int1 = floatInt($float1, $spot);
    $int2 = floatInt($float2, $spot);
    $int = $int1 + $int2;
    if ($rType == 1) {
        return $int;
    }
    return intFloatStr($int, $spot * $spot);
}

/**
 * 浮点数求差
 * @desc 前者-后者，相同位数的浮点数
 * @param $float1 浮点数1
 * @param $float2 浮点数2
 * @param $spot 浮点数位数
 * @param int $rType 返回类型：1整数、2小数
 * @return int|string
 */
function floatDiff($float1, $float2, $spot, $rType = 1) {
    $int1 = floatInt($float1, $spot);
    $int2 = floatInt($float2, $spot);
    $int = $int1 - $int2;
    if ($rType == 1) {
        return $int;
    }
    return intFloatStr($int, $spot);
}

function url_encode($str) {
    $str = urlencode($str);
    $arr = ['+'];
    foreach ($arr as $v) {
        if (strpos($str, $v)) {
            $str = str_replace($v, '_', $str);
            return $str;
        } else {
            return $str;
        }
    }
}

function url_decode($str) {
    $str = urldecode($str);
    $arr = ['_'];
    foreach ($arr as $v) {
        if (strpos($str, $v) != false) {
            $str = str_replace($v, '+', $str);
            return $str;
        } else {
            return $str;
        }
    }
}

/**
 * 金额千分化
 * @param $money
 * @return string
 */
function money_mil($money) {
    return number_format($money, 2, '.', ',');
}

/**
 * array(
 * array(5000, 5500),
 * array(6000, 6500),
 * array(8000, 8500)
 * )
 * 判断一个数组是否存在交集
 * @param $a
 * @return bool
 */
function arr_foo($a) {
    $r = array_unique(call_user_func_array('array_merge', $a));
    sort($r);

    foreach ($a as $v) {
        if (array_search($v[0], $r) != array_search($v[1], $r) - 1)
            return false;
    }
    return true;
}

/**
 * 列表金额显示万或者元
 * @param $data
 * @param $re
 * @param $unit
 */
function deal_money_list($data, &$re, &$unit) {
    //不足一万，处理成元
    if (strlen($data) <= 6 && !empty($data)) {
        $re = deal_data_list($data, 2);
        $unit = '元';
    } elseif (empty($data)) {
        $re = '';
        $unit = '';
    } else {
        $re = deal_data_list($data, 6);
        $unit = '万';
    }
}

/**
 * 列表金额取整
 * @param $data
 * @param $re
 * @param $unit
 */
function deal_data_list($data, $type) {
    if (empty($data)) {
        $data = '';
    } elseif (empty(ceil(intFloatStr($data, $type)))) {
        $data = '';
    } else {
        $data = (string)ceil(intFloatStr($data, $type));
    }
    return $data;
}

/**
 * 详情金额显示万或者元
 * @param $data
 * @param $re
 * @param $unit
 */
function deal_money_info($data, &$re, &$unit) {
    //不足一万，处理成元
    if (strlen($data) <= 6 && !empty($data)) {
        $re = deal_data_info($data, 2);
        $unit = '元';
    } elseif (empty($data)) {
        $re = '';
        $unit = '';
    } else {
        $re = deal_data_info($data, 6);
        $unit = '万';
    }
}

/**
 * 金额显示元
 * @param $data
 * @return string
 */
function export_money_info($data) {
    $re = deal_data_info($data, 2);
    $money = money_mil(floatval($re));
    return $money;
}

/**
 * 详情金额不取整
 * @param $data
 * @param $type
 * @return string
 */
function deal_data_info($data, $type) {
    if (empty($data)) {
        $data = '';
    } elseif (empty(intFloatStr($data, $type))) {
        $data = '';
    } else {
        $data = (string)intFloatStr($data, $type);
    }
    return $data;
}

/**
 * 列表面积,最低两位小数
 * @param $data
 * @param $type
 * @return string
 */
function deal_area_list($data, $type) {
    if (empty($data)) {
        $data = '';
    } elseif (empty(round(intFloatStr($data, $type), 2))) {
        $data = '';
    } else {
        $data = (string)round(intFloatStr($data, $type), 2);
    }
    return $data;
}

/**
 *  时间统计函数
 */
function microtime_float($time = null) {
    list($usec, $sec) = explode(' ', $time ? $time : microtime());
    return ((float)$usec + (float)$sec);
}

/**
 * 经纬度转city_code
 * @param $lat
 * @param $lng
 * @param $city_codes
 * @param $city_code
 * @throws \think\Exception
 */
function locationToCityCode($lat, $lng, &$city_codes, &$city_code) {
    $map = new BaiDu();
    $res = $map->getByLocation($lat, $lng);
    if ($res['result']['addressComponent']['adcode']) {
        $city_code = $res['result']['addressComponent']['adcode'];
        $p_codes = db('region')->where('city_code', $city_code)->value('p_codes');
        $city_codes = $p_codes . $city_code . ',';
    } else {
        $city_code = 0;
        $city_codes = 0;
    }
}

/**
 * 构造区间查询条件d
 * @param $params
 * @param $column
 * @return array
 */
function createSectionQuery1(string $params, string $column): array {
    $sectionArray = explode(',', $params);
    if (isset($sectionArray[1])) {//多选
        $arr = [];
        $arr[0] = $column;
        for ($index = 0; $index < count($sectionArray); $index++) {
            $sectionArray_ = explode('-', $sectionArray[$index]);
            if ($sectionArray_[1] == 0) {
                $wh = ['>=', $sectionArray_[0]];
            } elseif ($sectionArray_[0] == 0) {
                $wh = ['<=', $sectionArray_[1]];
            } else {
                $wh = ['between', $sectionArray_];
            }
            $arr[1][] = $wh;
        }
        $arr[2] = 'or';
    } else {
        $arrs = explode('-', $sectionArray[0]);
        if ($arrs[1] == 0) {
            $wh = ['>=', $arrs[0]];
        } elseif ($arrs[0] == 0) {
            $wh = ['<=', $arrs[1]];
        } else {
            $wh = ['between', $arrs];
        }
        $arr = [$column, $wh[0], $wh[1]];
    }
    return $arr;
}

/**
 * 折扣
 * @param string $params
 * @param string $column
 * @return array
 */
function createSectionDiscount(string $params, string $column): string {
    $sectionArray = explode(',', $params);
    $whereRaw = '';
    if (isset($sectionArray[1])) {//多选
        for ($index = 0; $index < count($sectionArray); $index++) {
            $sectionArray_ = explode('-', $sectionArray[$index]);
            $max = $sectionArray_[1] + 1;
            if ($sectionArray_[1] == 0) {
                $whereRaw .= "({$column} >= {$sectionArray_[0]}) or ";
            } elseif ($sectionArray_[0] == 0) {
                $whereRaw .= "({$column} < {$max}) or ";
            } else {
                $whereRaw .= "({$column} >= {$sectionArray_[0]} and {$column} < {$max}) or ";
            }
        }
        $whereRaw = substr($whereRaw, 0, strlen($whereRaw) - 3);
    } else {
        //单选
        $arrs = explode('-', $sectionArray[0]);
        $max = $arrs[1] + 1;
        if ($arrs[0] == 0) {
            $whereRaw .= "{$column} < $max ";
        } elseif ($arrs[1] == 0) {
            $whereRaw .= "{$column} >= {$arrs[0]}";
        } else {
            $whereRaw .= "{$column} >= {$arrs[0]} and {$column} < {$max} ";
        }
    }
    return $whereRaw;
}

/**
 * 导出csv文件
 * @param  $list //数据列表
 * @param $title //表头名称
 * 数据顺序要与表头顺序一致
 */
function exportCsv($list, $title) {
    $file_name = '房源列表' . date("YmdHis", time()) . ".csv";
    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment;filename=' . $file_name);
    header('Cache-Control: max-age=0');
    $file = fopen('php://output', "a");//打开php文件句柄，php://output表示直接输出到PHP缓存,a表示将输出的内容追加到文件末尾
    $limit = 1000;
    $calc = 0;
    //表头信息
    foreach ($title as $v) {
        $tit[] = iconv('UTF-8', 'GB2312//IGNORE', $v);//将utf-8编码转为gbk, Excel 打开 UTF-8 编码的 CSV 文件会导致汉字部分出现乱码
    }
    fputcsv($file, $tit);
    foreach ($list as $v) {
        $calc++;
        if ($limit == $calc) {
            //控制输出
            ob_flush();
            flush();
            $calc = 0;
        }
        foreach ($v as $t) {
            $tarr[] = iconv('UTF-8', 'GB2312//IGNORE', $t);
        }
        fputcsv($file, $tarr);
        unset($tarr);
    }
    unset($list);
    fclose($file);
    return true;
}

/**
 * csv文件导入
 * @param string $csv_file //文件名
 * @param int $maxline //读取几行，默认全部读取
 * @param int $offset //从第几行开始读取，默认第一行
 * @return array|bool
 */
function importCsv($csv_file = '', $maxline = 0, $offset = 0) {
    set_time_limit(0);//防止超时
    //ini_set("memory_limit", "512M");//防止内存溢出
    if (!$fp = fopen($csv_file, 'r')) {
        Err::add('文件导入失败');
        return false;//文件打开失败
    }
    while (false !== ($line = fgets($fp))) {
//        $line = mb_convert_encoding(, 'utf-8', ['GBK','GB18030', 'BIG-5']);
        $line = iconv("gbk", "UTF-8//IGNORE", $line);//转化编码
        $line = str_replace(array("\n", "\r", " "), array("", "", ""), $line);
        $line = trim($line, ',');
        break;
    }
    $data = array();
    $head = explode(',', $line);//表头
    $i = 0;
    while ($linedata = fgetcsv($fp)) {
        //小于偏移量则不读取,但$i仍然需要自增
        if ($i++ < $offset) {
            continue;
        }
        //大于读取行数则退出
        if ($i > $maxline && $maxline) {
            break;//文件行数超出读取行数,则结束循环并返回已读数据
        }

        for ($j = 0; $j < count($linedata); $j++) {
            //防止乱码,内容自动识别编码
//            $newitem[$i] = mb_convert_encoding($linedata[$i], 'UTF-8', ['GBK','GB18030', 'BIG-5']);
            $newitem[$j] = iconv("gbk", "UTF-8//IGNORE", $linedata[$j]);//转化编码;
        }
        $data[] = $newitem;

    }
    fclose($fp);
    return array('head' => $head, 'data' => $data);

}

/**
 * 文件验证
 * @param $file 上传文件
 * @param $config 验证配置项
 * @return bool|string
 */
function verifyFile($file, $config) {
    // 文件错误
    if ($file['error'] > 0) {
        Err::add('文件错误');
        return false;
    }

    // 文件后缀
    $arr = explode('.', $file['name']);
    $ext = end($arr);
    if (!in_array($ext, $config['ext'])) {
        Err::add('文件后缀错误');
        return false;
    }

    // 文件大小， 注意配置项需要以字节为单位 1M = 1024 * 1024
    if ($file['size'] > $config['size']) {
        Err::add('文件过大');
        return false;
    }
    return true;
}

/**
 * 列表金额显示万或者元
 * @param $data
 * @param $re
 * @param $unit
 */
function deal_round_money_list($data, &$re, &$unit) {
    //不足一万，处理成元
    if (strlen($data) <= 6 && !empty($data)) {
        $re = deal_round_data_list($data, 2);
        $unit = '元';
    } elseif (empty($data)) {
        $re = '';
        $unit = '';
    } else {
        $re = deal_round_data_list($data, 6);
        $unit = '万';
    }
}

/**
 * 列表金额取整(四舍五入)
 * @param $data
 * @param $re
 * @param $unit
 */
function deal_round_data_list($data, $type) {
    if (empty($data)) {
        $data = '';
    } elseif (empty(round(intFloatStr($data, $type)))) {
        $data = '';
    } else {
        $data = (string)round(intFloatStr($data, $type));
    }
    return $data;
}

/**
 * 接管错误
 * @param $errno
 * @param $errstr
 * @param $errfile
 * @param $errline
 */
function my_customError($errno, $errstr, $errfile, $errline) {
    $err = "错误等级:{$errno} | 错误信息:{$errstr} | 错误所在的代码行:{$errline} | 文件{$errfile} | php 版本 " . PHP_VERSION . "(" . PHP_OS . ")";
    $file = pathinfo ($errfile);
    Log::write ($err, explode ('.', $file['basename'])[0] . '.errMsg');
}

/**
 * 自定义链接
 * @param $configs
 * @param $tName
 * @throws \think\Exception
 */
function connectDb($configs, $tName) {
    $tName = "{$configs['prefix']}{$tName}";
    Db::connect("mysql://{$configs['username']}:{$configs['pwd']}@{$configs['host']}:{$configs['port']}/{$configs['dbname']}#utf8")->table("{$tName}");
}

/**
 * 金额转换
 * @param $arr
 * @throws \think\Exception
 */
function price_arr_deal($arr, $type) {
//    1元转分、2分转元、3分转万
    if (isset($arr['initial_price']))
        $arr['initial_price'] = moneyFormat($arr['initial_price'], $type);
    if (isset($arr['final_price']))
        $arr['final_price'] = moneyFormat($arr['final_price'], $type);
    if (isset($arr['bond']))
        $arr['bond'] = moneyFormat($arr['bond'], $type);
    if (isset($arr['consult_price']))
        $arr['consult_price'] = moneyFormat($arr['consult_price'], $type);
    if (isset($arr['market_price']))
        $arr['market_price'] = moneyFormat($arr['market_price'], $type);
    if (isset($arr['price_lower_offset']))
        $arr['price_lower_offset'] = moneyFormat($arr['price_lower_offset'], $type);
    if (isset($arr['anjuke_price']))
        $arr['anjuke_price'] = moneyFormat($arr['anjuke_price'], $type);
    return $arr;
}

if (!function_exists("fastcgi_finish_request")) {
    function fastcgi_finish_request() {
    }
}

//判断图片是否存在
function img_exists($url){
    $ch = curl_init();
    $timeout = 600;
    curl_setopt ($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $result = curl_exec($ch);
    if (preg_match("/200 OK/", $result)){
        return true;
    }else{
        return false;
    }

}

/**
 * 去除特殊字符
 * @param $strParam
 * @return string|string[]|null
 */
function replaceSpecialChar($strParam) {
    $regex = "/\(|\)|\（|\）/";
    return preg_replace($regex, "", $strParam);
}

/**
 * 通过代理ip请求目标网站
 * @param $url
 * @return string
 */
function xhr_proxy($url, $method) {
    $redis = Redis::getInstance();
    $curl = Curl::getInstance();
    $ips = $redis->get('proxy_ips');
    if (!$ips) {
        sleep(1);
        $curl->setProxy('', '');
        $arr = get_proxy();
        if (!isset($arr['data']) || empty($arr['data'])) Log::write($arr['msg'] ?? '获取代理ip失败', "xhr_proxy.log");
        $ips = $arr['data'];
    } else {
        $ips = json_decode($ips, true);
    }
    while (1):
        if (empty($ips)) {
            sleep(1);
            $curl->setProxy('', '');
            $arr2 = get_proxy();
            if (!isset($arr2['data']) || empty($arr2['data'])) Log::write($arr['msg'] ?? '获取代理ip失败', "xhr_proxy.log");
            $ips = $arr2['data'];
            continue;
        }
//        print_r($ips);
//        echo "\n";
        $curl->setProxy($ips[0]['ip'], (string)$ips[0]['port']);
        //请求目标网站
        $ret = $curl->xhr($method, $url);
        if (!$ret) {
//            echo "无效代理ip\n";
            $ips = [];
            continue;
        } elseif (!is_array(json_decode($ret, true))) {
//            echo "无效数据\n";
            $ips = [];
            continue;
        } else {
            break;
        }
    endwhile;
//    echo "保存有效ip\n";
    if (!$redis->setex('proxy_ips', 3600, json_encode($ips))) Log::write('缓存代理ip失败', "xhr_proxy.log");
    return $ret;
}

/**
 * 获取代理ip
 * @return mixed
 */
function get_proxy() {
    $curl = Curl::getInstance();
    return json_decode($curl->xhr("GET", 'http://d.jghttp.golangapi.com/getip?num=1&type=2&pro=0&city=0&yys=0&port=11&pack=32327&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1&regions='), true);
}

/**
 * 房源排序
 * @param $order
 * @return array
 */
function house_order($order){
    if (!empty($order)) {
        switch ($order) {
            case 1:
                //默认
                $orderBy = ['ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'initial_price' => 'asc', 'ha.discount' => 'asc'];
                break;
            case 2:
                //按价格从高到低
                $orderBy = ['initial_price' => 'desc', 'ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'ha.discount' => 'asc'];
                break;
            case 3:
                //按价格从低到高
                $orderBy = ['initial_price' => 'asc', 'ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'ha.discount' => 'asc'];
                break;
            case 4:
                //按折扣从高到低
                $orderBy = ['ha.discount' => 'desc', 'ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'initial_price' => 'asc'];
                break;
            case 5:
                //按折扣从低到高
                $orderBy = ['ha.discount' => 'asc', 'ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'initial_price' => 'asc'];
                break;
            case 6:
                //开拍时间由远及近
                $orderBy = ['ha.start_time' => 'desc', 'ha.auction_status' => 'asc', 'initial_price' => 'asc', 'ha.discount' => 'asc'];
                break;
            case 7:
                //开拍时间由近及远
                $orderBy = ['ha.start_time' => 'asc', 'ha.auction_status' => 'asc', 'initial_price' => 'asc', 'ha.discount' => 'asc'];
                break;
            case 8:
                //最近发布
                $orderBy = ['h.on_time' => 'desc', 'ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'initial_price' => 'asc', 'ha.discount' => 'asc'];
                break;
            default:
                $orderBy = ['ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'initial_price' => 'asc', 'ha.discount' => 'asc'];
                break;
        }
    } else {
        $orderBy = ['ha.auction_status' => 'asc', 'ha.start_time' => 'asc', 'initial_price' => 'asc', 'ha.discount' => 'asc'];
    }
    return $orderBy;
}